<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>symbol类型</title>
  <style>
    div, li, p {
      line-height: 40px;
    }
    span {
      color: red;;
    }
  </style>
</head>
<body>
  <h2>概述</h2>
  <ul>
    <li>
        symbol类型表示独一无二的值,它是javascript语言的第七种数据类型。也就是说现在对象的属性名可以有两种数据类型，一种是原来就有的字符串，另一种是新增的Symbol类型。只要属性名属于Symbol类型，就是独一无二的。可以保证不会与其他属性名产生冲突
    </li>
    <li>
      Symbol函数前不能使用new命令，因为生成的Symbol是一个原始类型的值，不是对象。也就是说，由于Symbol值不是对象，所以不能添加属性。基本上，它是一种类似于字符串的数据类型
    </li>
    <li>
      Symbol函数可以接受一个字符串做欸参数，表示对Symbol实例的描述，主要是为了在控制台显示，或者转为字符串时比较容易区分。有了参数以后，就等于为它们加上了描述，输出时能够区分到底是哪一个值 <span>
        Symbol函数的参数只表示对当前Symbol值的描述，因此相同参数的Symbol函数的返回值是不相等的
      </span>
    </li>
    <li>
      Symbol值作为对象属性名时不能使用点运算符，因为点运算符后面总是字符串，所以不会读取mySymbol作为标识名所指代的值，导致a的属性名实际上是一个字符串，而不是一个Symbol值。同理，在对象的内部，使用Symbol值定义属性时，Symbol值必须放在方括号中。
    </li>
    <li>
      symbol作为属性名，该属性不会出现在for ... in、for ... of循环中，也不会被Object.keys()、Object.getOwnpropertyName()返回，但它也不是私有属性，有一个Object.getOwnProPertySymbols方法返回一个数组，成员时当前对象的所有用Symbol类型属性名的键
    </li>
    <li>
      另一个新的API-Reflect.ownKeys方法可以返回所有类型的键名，包括常规键名和Symbol键名
    </li>
    <li>
      以Symbol值作为名称的属性不会被常规方法遍历得到。我们可以利用这个特性为对象定义一些非私有但又希望只用于内部的方法。
    </li>
    <li>
      有时，我们希望重新使用同一个Symbol值，Symbol.for()方法可以做到这一点。它接受一个字符串作为参数，然后搜索有没有以该参数作为名称的Symbol值。如果有，就返回这个Symbol值，否则就新建一个以该字符串为名称的Symbol值
    </li>
    <li>
      Symbol.for()与Symbol()这两个方法都会生成Symbol。他们的区别是，前者会被登记在全局环境中供搜索，而后者不会。Symbol.for()不会在每次调用时都返回一个新的Symbol类型的值，而是会先检查给定的key是否存在，如果不存在才会新建一个值。比如，如果调用Symbol.for('cat')30次，每次都会返回同一个Symbol的值，但是调用Symbol('cat')30次，则会返回30个不同的Symbol值
    </li>
    <li>
      Symbol()写法没有登记机制，<span>Symbol.keyFor()方法返回一个已登记的Symbol类型的key</span>
    </li>
  </ul>
</body>
</html>